/****************************************************
          File Name:internet_domain-1.c
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Fri 03 Oct 2014 02:17:51 PM CST

*****************************************************/

#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif

#include"net.h"
#include"toDaemon.h"
#include<signal.h>
#include<sys/wait.h>

static int sfd;

static void dealing(int sig)
{
    close(sfd);
//	raise(sig);  	/* restore default sigaction */
	raise(SIGKILL); 	/* temporary solution */
}

int get_msg(int acfd)
{
	char *buf;
	int bytes;
	
	buf=malloc(SIZE);
	if(acfd==-1)
		err("accept");
	while((bytes=read(acfd,buf,SIZE))>0)
		if(write(STDOUT_FILENO,buf,bytes)!=bytes)
			err("write");
	if(bytes==-1)
		err("read");
	if(close(acfd)==-1)
		err("close");
	free(buf);
	return 0;
}

int main(int argc, char *argv[])
{
    if(argc<2 || strcmp(argv[1],"--help")==0)
    {
        printf("%s ipv4addr # 127.0.0.1 (for example)\nor \
        \n%s any # random ip addr\n",argv[0],argv[0]);
        exit(1);
    }
    int acfd, bytes;
    struct sockaddr_in addr;
    int ipaddr; 
 
	struct sigaction act;
	
	if(toDaemon()==-1) 			/* make a daemon */
		err("toDaemon");
    
	if(inet_pton(AF_INET,argv[1],&ipaddr)==-1)
        err("get ip addr");
    sfd=socket(AF_INET,SOCK_STREAM,0);
    if(sfd==-1)
        err("socket");
    memset(&addr,0,sizeof(struct sockaddr_in));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(8888);
    addr.sin_addr.s_addr=strcmp(argv[1],"any")==0?INADDR_ANY:ipaddr;
    if(bind(sfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))==-1)
        err("bind");
    listen(sfd,5);

    sigemptyset(&act.sa_mask);
	act.sa_flags=0;
	act.sa_handler=dealing;
	if(sigaction(SIGTERM,&act,NULL)==-1)
		err("sigaction");
	signal(SIGCHLD,SIG_IGN);  		/* 显式的忽略SIGCHLD防止zombie的产生 */
    for(;;)
    {
        acfd=accept(sfd,NULL,NULL);
		
		switch(fork())
		{
			case -1:
				err("frok");
			case 0:
				get_msg(acfd);
				printf("\e[32mchild returned\e[0m\n");
				_exit(0); 			/* child process exit here */
		}
		close(acfd);
	}
}
